home *** CD-ROM | disk | FTP | other *** search
/ fxPAINT 1.0 / fxPAINT 1.0.iso / tools / ics / software / ics.lzh / ICS / Programmer / Example2.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-07-01  |  12.2 KB  |  287 lines

  1. /**********************************************************/
  2. /* Copyright   ©1999 Wolf-Juergen Faust                   */
  3. /* Am Dorfgarten 10                                       */
  4. /* 60435 Frankfurt      EXAMPLE2.c                        */
  5. /* Germany                                                */
  6. /* Tel: +(49) 69 5486556                                  */
  7. /* Fax: +(49) 69 95409598                                 */
  8. /* email: wfaust@stud.uni-frankfurt.de                    */
  9. /*                                                        */
  10. /*                                                        */
  11. /* This piece of source code is part of the current       */
  12. /* ICSConvert version and shows how to call ICS.          */
  13. /* See the included comments and ICS.doc for more         */
  14. /* info when adding ICS support to your software          */
  15. /*                                                        */
  16. /* Unlike Example.c this file corrects multiple pixels    */
  17. /* with a single call to TranslateColors().               */
  18. /*                                                        */
  19. /**********************************************************/
  20.  
  21. #include    <proto/ics.h>
  22.  
  23. struct Library *ICSBase=NULL;
  24.  
  25. /*** VARS ***/
  26.  
  27. UWORD LoadPic(struct Window *, UBYTE *inputfile, UBYTE *outputfile, BOOL nosetup, BOOL nostatus, BOOL nocolor, PSTR prefsfile);
  28. UWORD LoadPic(struct Window *win2, UBYTE *inputfile, UBYTE *outputfile, BOOL nosetup, BOOL nostatus, BOOL nocolor, PSTR prefsfile)
  29. #endif
  30.  
  31. /*** MAIN ***/
  32. {
  33.     UWORD ret = 1;
  34.  
  35.     UWORD wi;
  36.     ULONG x,y, li;
  37.     ULONG size;
  38.     struct IFFHandle *iffhandle;
  39.     UBYTE *temp;
  40.     static void *idc=NULL;
  41.     static void *idctrans=NULL;
  42.     UBYTE *r,*g,*b;
  43.     LONG ifferr;
  44.     struct MyHandle *ilbm;
  45.     struct URGBCOLOR *rgb;
  46.     struct UGRAYCOLOR *gray;
  47.     void *linebuffer;
  48.     COLORTYPE savemode;
  49.  
  50.     if(!inputfile) // signal we want to free all allocated handles?
  51.     {
  52.         if(idctrans)
  53.         {
  54.             DeleteIDCTransform(idctrans);
  55.             idctrans = NULL;
  56.         }
  57.         if(idc)
  58.         {
  59.             DeleteIDC(idc);
  60.             idc = NULL;
  61.         }
  62.         return(0);
  63.     }
  64.     if(!idc) // create a device context if not already present (idc is 
  65.     {
  66.         if(!(idc = CreateIDC(                // create ICS device context object
  67.             ICS_APPNAME, PRGMNAME,           // name of this application
  68.             ICS_APPNAMEVERSION, NUMVERSION,  // version of this application
  69.             ICS_APPICSVERSION, 2,            // version of ICS library this application was made for/with
  70.             ICS_PREFSFILE, prefsfile,
  71.             TAG_DONE)))
  72.         {
  73.             ErrMes(win2, MSG_ICSERR_NOCONTEXT); // Error: Can't create device context using ics.library\n      Maybe not enough memory?
  74.             return(0);
  75.         }
  76.     }
  77.     if(!nosetup) // Does calling function want a setup?
  78.     {
  79.         if(idctrans) // delete any old transformation before new setup.
  80.         {
  81.             DeleteIDCTransform(idctrans);
  82.             idctrans = NULL;
  83.         }
  84.         if(SetupIDCColorMatching(idc, dscreen, TAG_DONE)<=1)  // display ICS preference window. Note: ICSConvert currently does not offer any GUI. So I abort if the user selects cancel...   - returns 0=err, 1=user cancel
  85.         {
  86.             temp = ICSFault(idc, MyGetString(MSG_ICSERR_MSGHEADER)); // Error while running ICSConvert.
  87.             if(!temp) temp = MyGetString(MSG_ICSERR_NOPREFS); // "Error: Can't open ICS preferences.";
  88.             if(ICSErr(idc)>ICS_ERRMSGLIMIT) Mes(temp, win2);
  89.             return(0);
  90.         }
  91.     }
  92.     if(idctrans) ICSStatusWin(idctrans, ICS_StatusText,  MyGetString(MSG_ICSSTATUS_OPENSRCFILE), TAG_DONE);  // change title and text of status window created by ICS library during CreateIDCTransform(): "Opening image file..."
  93.     sprintf(tempstr, PRGMNAME": %s", FilePart(inputfile)); // Generate window title of ICS status window
  94.     if(strlen(tempstr) > 35) sprintf(tempstr, "ICS: %s", FilePart(inputfile));
  95.     if(strlen(tempstr) > 35) stccpy(tempstr, MyGetString(MSG_ICSSTATUS_TITLE), 35);
  96.     if(!idctrans) // Is there a transformation function available from a previous call - if not, make one now
  97.     {
  98.         if(!(idctrans = CreateIDCTransform(idc,
  99.             ICS_TransferDevices, ICS_INPUT_DEVICE,        // We want to convert from input to display device (not printer device)
  100.             ((nostatus) ? TAG_DONE: ICS_StatusOpen), dscreen,                      // Screen to use for status window or NULL for default public screen
  101.             ICS_StatusTitle, tempstr, //  Overwrite status window title with our own: "ICS Image Conversion"
  102.             //ICS_StatusActivate, TRUE,                     // Activate status window
  103.             ICS_StatusKeep, TRUE,                         // keep status window open as we use the ics status window during conversion of image data later
  104.             // ICS_StatusDisableAbort, TRUE,                 // use this to disable Abort/Stop button
  105.             TAG_DONE))) // create input (scanner) to device (display/monitor) color corretion and show status window while processing.. leave status window open for user below...
  106.         {
  107.             temp = ICSFault(idc, MyGetString(MSG_ICSERR_MSGHEADER)); // Error while running ICSConvert.
  108.             if(!temp) temp = MyGetString(MSG_ICSERR_CREATETRANSFORM); // Error: Can't create color transformation using ics.library.
  109.             if(ICSErr(idc)>ICS_ERRMSGLIMIT) Mes(temp, win2);
  110.             return(0);
  111.         }
  112.     } else
  113.     {
  114.         ICSStatusWin(idctrans, ICS_StatusTitle, tempstr, ICS_StatusText,  MyGetString(MSG_ICSSTATUS_OPENSRCFILE), TAG_DONE);  // change status window for new file
  115.     }
  116.     if(ret)
  117.     {
  118.         if(ICSStatusWin(idctrans, ICS_StatusCheck,  0, TAG_DONE))
  119.         {
  120.             ret = 0;
  121.         }
  122.     }
  123.     if(ilbm = (struct MyHandle *) AllocVec(sizeof(struct MyHandle), MEMF_PUBLIC|MEMF_CLEAR))
  124.     {
  125.         stccpy(ilbm->prtfile, inputfile, PATH);
  126.         stccpy(ilbm->savefile, outputfile, PATH);
  127.  
  128.         if(insema = (struct SignalSemaphore *) AllocVec(sizeof(struct SignalSemaphore),MEMF_PUBLIC|MEMF_CLEAR)) // Semaphore used by the image reading routine GetMain()
  129.         {
  130.             InitSemaphore(insema);
  131.  
  132.             if(ret)
  133.             {
  134.                 ilbm->memory = 2;    // Reading routine may use more memory...
  135.                 ilbm->landscape=0;   // No landscape rotation wanted of input
  136.                 if (GetMain(ilbm, POPEN, win2, 0))  // open source image file for conversion
  137.                 {
  138.                     ilbm->savemode = ilbm->destmode; // set var indicating the output file type: 1=gray 0=color depending on input ("destmode" is the input file mode),
  139.                     if(nocolor) ilbm->savemode = 1;  // user asked for grayscale only output?
  140.                     if (GetMain(ilbm, PREADINIT, win2, 0))  // init read routines for file
  141.                     {
  142.                         size = ilbm->wssize * ( (ilbm->destmode)  ? sizeof(struct UGRAYCOLOR) : sizeof(struct URGBCOLOR) );
  143.                         if(linebuffer = AllocVec(size, MEMF_CLEAR))
  144.                         {
  145.                             ICSStatusWin(idctrans, ICS_StatusText,  MyGetString(MSG_ICSSTATUS_OPENDESTFILE), TAG_DONE);  // "Opening destination file"
  146.                             if(iffhandle = OPENMYFILE(ilbm, win2)) // open destination image file for color corrected image
  147.                             {
  148.                                 if(ifferr = PushChunk(iffhandle,ID_ILBM,ID_BODY,IFFSIZE_UNKNOWN)) // Start writing the main body of destination image file
  149.                                 {
  150.                                     ErrMes(win2, MSG_IFFERR_WRITECHUNK, ifferr, "BODY", ( (strlen(ilbm->savefile)>60) ? FilePart(ilbm->savefile) : ilbm->savefile )); // Error (Type %ld): Can't write '%s' chunk of\ndestination file: '%s'.
  151.                                     ret = 0;
  152.                                 } else
  153.                                 {
  154.                                     if (SetSignal(0,0) & SIGBREAKF_CTRL_C) ret=0; // check if user aborted ICSConvert...
  155.                                     for(ret=1,y=0; (ret) && (y<ilbm->hssize); y++)  // loop for number of lines in image
  156.                                     {
  157.                                         // Display progress status and check for user abort...
  158.                                         sprintf(tempstr, MyGetString(MSG_ICSSTATUS_COMPLETE), (y*100)/ilbm->hssize); // Converting Image  -  %ld%% complete
  159.                                          // change status text and update progress bar. Also check if user wants to abort...
  160.                                         if(ICSStatusWin(idctrans, ICS_StatusText,  tempstr, ICS_StatusProgress, (y*100)/ilbm->hssize, ICS_StatusCheck,  0, TAG_DONE))
  161.                                         {
  162.                                             ret = 0;
  163.                                             break;
  164.                                         }
  165.                                         // read a single image line into buffer.
  166.                                         if(temp = (UBYTE *)GetMain(ilbm, PREADLINE, win2, y))
  167.                                         {
  168.                                             if(ilbm->destmode) // is source a grayscale image?  Note: white=255  gray=0
  169.                                             {
  170.                                                 for(x=0, gray=linebuffer; (ret) && (x<ilbm->wssize); x++, gray++)  // loop for number of pixels in line
  171.                                                 {
  172.                                                     gray->gray = (temp[x]<<8) | temp[x];  // convert 8 bit to 16 bit unsigned graylevel. IMPORTANT: Black=0   White=65535
  173.                                                 }
  174.                                                 if(!(TranslateColors(idctrans, linebuffer, ilbm->wssize, COLOR_UGRAY, linebuffer, COLOR_UGRAY)))
  175.                                                 {
  176.                                                     temp = ICSFault(idc, MyGetString(MSG_ICSERR_CONVERT)); // Error while converting color using ICS.
  177.                                                     if(!temp) temp = MyGetString(MSG_ICSERR_CONVERT);
  178.                                                     if(ICSErr(idc)>ICS_ERRMSGLIMIT) Mes(temp, win2);
  179.                                                     ret = 0;
  180.                                                     break;
  181.                                                 }
  182.                                                 r = temp;
  183.                                                 for(x=0, gray=linebuffer; (ret) && (x<ilbm->wssize); x++, gray++)  // loop for number of pixels in line
  184.                                                 {
  185.                                                     *r++ = gray->gray >> 8;
  186.                                                 }
  187.                                             } else
  188.                                             {
  189.                                                 r = temp;
  190.                                                 g = r + ilbm->wssize;
  191.                                                 b = g + ilbm->wssize;
  192.     
  193.                                                 for(x=0, rgb=linebuffer; (ret) && (x<ilbm->wssize); x++, rgb++)  // loop for number of pixels in line
  194.                                                 {
  195.                                                     rgb->red   = (r[x]<<8) | r[x];  // convert 8 bit to 16 bit unsigned RGB color
  196.                                                     rgb->green = (g[x]<<8) | g[x];
  197.                                                     rgb->blue  = (b[x]<<8) | b[x];
  198.                                                 }
  199.                                                 savemode = ((ilbm->savemode) ? COLOR_UGRAY : COLOR_URGB); // note: linebuffer is used as input and output but input maybe URGB while output is UGRAY. This only works because UGRAY is smaller than URGB.
  200.                                                 if(!(TranslateColors(idctrans, linebuffer, ilbm->wssize, COLOR_URGB, linebuffer, savemode)))
  201.                                                 {
  202.                                                     temp = ICSFault(idc, MyGetString(MSG_ICSERR_CONVERT)); // Error while converting color using ICS.
  203.                                                     if(!temp) temp = MyGetString(MSG_ICSERR_CONVERT);
  204.                                                     if(ICSErr(idc)>ICS_ERRMSGLIMIT) Mes(temp, win2);
  205.                                                     ret = 0;
  206.                                                     break;
  207.                                                 }
  208.                                                 if(ilbm->savemode) // is the output gray or color?
  209.                                                 {
  210.                                                     r = temp;
  211.                                                     for(x=0, gray=linebuffer; (ret) && (x<ilbm->wssize); x++, gray++)  // loop for number of pixels in line
  212.                                                     {
  213.                                                         *r++ = gray->gray >> 8;
  214.                                                     }
  215.                                                 } else
  216.                                                 {
  217.                                                     r = temp;
  218.                                                     g = r + ilbm->wssize;
  219.                                                     b = g + ilbm->wssize;
  220.                                                     for(x=0, rgb=linebuffer; (ret) && (x<ilbm->wssize); x++, rgb++)  // loop for number of pixels in line
  221.                                                     {
  222.                                                         *r++ = rgb->red >> 8;      // Convert 16 to 8 Bit - Correct would be to devide by 65535/255=257 and not 256... but we ignore the invisible fault introduced...
  223.                                                         *g++ = rgb->green >> 8;
  224.                                                         *b++ = rgb->blue >> 8;
  225.                                                         //KPrintF("x %ld  %ld %ld %ld\n",r[x],g[x],b[x]);
  226.                                                     }
  227.                                                 }
  228.                                             }
  229.                                             if(!(WRITEMYLINE(ilbm, win2, iffhandle, temp)))
  230.                                             {
  231.                                                 ret = 0;
  232.                                                 break;
  233.                                             }
  234.                                         } else
  235.                                         {
  236.                                             ret = 0;
  237.                                             break;
  238.                                         }
  239.                                         if (SetSignal(0,0) & SIGBREAKF_CTRL_C) ret=0;
  240.                                     }
  241.                                     if(ret)
  242.                                     {
  243.                                         if(ifferr = PopChunk(iffhandle))
  244.                                         {
  245.                                             ErrMes(win2, MSG_IFFERR_WRITECHUNK, ifferr, "BODY", ( (strlen(ilbm->savefile)>60) ? FilePart(ilbm->savefile) : ilbm->savefile )); // Error (Type %ld): Can't write '%s' chunk of\ndestination file: '%s'.
  246.                                             ret = 0;
  247.                                         }
  248.                                     }
  249.                                 }
  250.                                 ICSStatusWin(idctrans, ICS_StatusText,  MyGetString(MSG_ICSSTATUS_CLOSING), TAG_DONE);  // Closing source and destination file
  251.                                 CLOSEMYFILE(iffhandle);
  252.                                 if( (!ret) && (iffhandle) ) // Delete written file after error
  253.                                 {
  254.                                     DeleteFile(ilbm->savefile);
  255.                                 }
  256.                             }
  257.                             FreeVec(linebuffer);
  258.                         } else
  259.                         {
  260.                             ErrMes(NULL, MSG_ERR_MEMORY, size); // Not enough free memory.\nFailed to get %ld bytes.
  261.                         }
  262.                         GetMain(ilbm, PREADEND, win2, 0);
  263.                     } else
  264.                     {
  265.                         ret = 0;
  266.                     }
  267.                     GetMain(ilbm, PCLOSE, win2, 0);
  268.                     ICSStatusWin(idctrans, ICS_StatusText,  MyGetString(MSG_ICSSTATUS_FINISH), TAG_DONE);  // Finished processing of file
  269.                 } else
  270.                 {
  271.                     ret = 0;
  272.                 }
  273.             }
  274.             FreeVec(insema);
  275.         } else
  276.         {
  277.             ErrMes(win2, MSG_ERR_MEMORY, sizeof(struct SignalSemaphore)); // Not enough free memory.\nFailed to get %ld bytes.
  278.             ret = 0;
  279.         }
  280.         FreeVec(ilbm);
  281.     } else
  282.     {
  283.         ErrMes(NULL, MSG_ERR_MEMORY, sizeof(struct MyHandle)); // Not enough free memory.\nFailed to get %ld bytes.
  284.     }
  285.     return(ret);
  286. }
  287.